package com.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.dao.ZhishixinxiRepository;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;

import com.utils.ValidatorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.annotation.IgnoreAuth;

import com.entity.ZhishixinxiEntity;
import com.entity.view.ZhishixinxiView;

import com.service.ZhishixinxiService;
import com.service.TokenService;
import com.utils.PageUtils;
import com.utils.R;
import com.utils.MD5Util;
import com.utils.MPUtil;
import com.utils.CommonUtil;
import java.io.IOException;
import com.service.StoreupService;
import com.entity.StoreupEntity;
import org.springframework.web.client.RestTemplate;

/**
 * 知识信息 后端接口
 *
 * @author
 * @email
 * @date 2022-03-24 19:25:36
 */
@Slf4j
@RestController
@RequestMapping("/zhishixinxi")
public class ZhishixinxiController {

  @Autowired
  private ZhishixinxiService zhishixinxiService;

  @Autowired
  private StoreupService storeupService;

  @Autowired
  private ZhishixinxiRepository zhishixinxiRepository;

  @Autowired
  private ElasticsearchTemplate elasticsearchTemplate;


  /**
   * 后端列表，已改为ES
   */
  @RequestMapping("/page")
  public R page(@RequestParam Map<String, Object> params, ZhishixinxiEntity zhishixinxi,
      HttpServletRequest request) {
    String tableName = request.getSession().getAttribute("tableName").toString();
    if (tableName.equals("yonghu")) {
      zhishixinxi.setYonghuzhanghao((String) request.getSession().getAttribute("username"));
    }
//    EntityWrapper<ZhishixinxiEntity> ew = new EntityWrapper<ZhishixinxiEntity>();
//    PageUtils page = zhishixinxiService.queryPage(params,
//        MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, zhishixinxi), params), params));
//
//    return R.ok().put("data", page);

    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    String pageNo = (String) params.get("page");
    String limit = (String) params.get("limit");
    if (params.containsKey("xiangmufenlei")) {
      String xiangmufenlei = (String) params.get("xiangmufenlei");
      queryBuilder.withQuery(
          boolQueryBuilder.must(QueryBuilders.termQuery("xiangmufenlei", xiangmufenlei)));
    }
    if (params.containsKey("biaoqianfenlei")) {
      String biaoqianfenlei = (String) params.get("biaoqianfenlei");
      queryBuilder.withQuery(
          boolQueryBuilder.must(QueryBuilders.termQuery("biaoqianfenlei", biaoqianfenlei)));
    }
    if (params.containsKey("zhishineirong")) {
      String zhishineirong = (String) params.get("zhishineirong");
      zhishineirong = StrUtil.removePrefix(zhishineirong, "%");
      zhishineirong = StrUtil.removeSuffix(zhishineirong, "%");
      queryBuilder.withQuery(
          boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("zhishineirong", zhishineirong)));
    }
    if (params.containsKey("zhishibiaoti")) {
      String zhishibiaoti = (String) params.get("zhishibiaoti");
      zhishibiaoti = StrUtil.removePrefix(zhishibiaoti, "%");
      zhishibiaoti = StrUtil.removeSuffix(zhishibiaoti, "%");
      queryBuilder.withQuery(
          boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("zhishibiaoti", zhishibiaoti)));
    }
    if (tableName.equals("yonghu")) {
      queryBuilder.withQuery(boolQueryBuilder.must(QueryBuilders.termQuery("yonghuzhanghao", zhishixinxi.getYonghuzhanghao())));
    }

    // 按时间排个序
    queryBuilder.withSort(SortBuilders.fieldSort("addtime").order(SortOrder.DESC));

    // 分页
    queryBuilder.withPageable(PageRequest.of(Integer.parseInt(pageNo) - 1, Integer.parseInt(limit)));

    Page<ZhishixinxiEntity> pageResult = zhishixinxiRepository.search(queryBuilder.build());
    PageUtils pageUtils = new PageUtils(pageResult.getContent(),
        Convert.convert(new TypeReference<Integer>() {
        }, pageResult.getTotalElements()), pageResult.getSize(), pageResult.getNumber());
    return R.ok().put("data", pageUtils);

  }

  /**
   * 前端列表，已改为ES
   */
  @IgnoreAuth
  @RequestMapping("/list")
  public R list(@RequestParam Map<String, Object> params, ZhishixinxiEntity zhishixinxi,
      HttpServletRequest request) {
//        EntityWrapper<ZhishixinxiEntity> ew = new EntityWrapper<ZhishixinxiEntity>();
//		PageUtils page = zhishixinxiService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, zhishixinxi), params), params));
//        return R.ok().put("data", page);
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    String pageNo = (String) params.get("page");
    String limit = (String) params.get("limit");
    String sfsh = (String) params.get("sfsh");
    queryBuilder.withQuery(boolQueryBuilder.must(QueryBuilders.termQuery("sfsh", sfsh)));
    if (params.containsKey("xiangmufenlei")) {
      String xiangmufenlei = (String) params.get("xiangmufenlei");
      queryBuilder.withQuery(
          boolQueryBuilder.must(QueryBuilders.termQuery("xiangmufenlei", xiangmufenlei)));
    }

    if (params.containsKey("biaoqianfenlei")) {
      String biaoqianfenlei = (String) params.get("biaoqianfenlei");
      queryBuilder.withQuery(
          boolQueryBuilder.must(QueryBuilders.termQuery("biaoqianfenlei", biaoqianfenlei)));
    }
    if (params.containsKey("zhishineirong")) {
      String zhishineirong = (String) params.get("zhishineirong");
      zhishineirong = StrUtil.removePrefix(zhishineirong, "%");
      zhishineirong = StrUtil.removeSuffix(zhishineirong, "%");

      // 设置内容的分词格式
      MatchPhraseQueryBuilder matchPhraseQuery = QueryBuilders
          .matchPhraseQuery("zhishineirong", zhishineirong).slop(5);

      queryBuilder.withQuery(
          boolQueryBuilder.must(matchPhraseQuery));
    }
    if (params.containsKey("zhishibiaoti")) {
      String zhishibiaoti = (String) params.get("zhishibiaoti");
      zhishibiaoti = StrUtil.removePrefix(zhishibiaoti, "%");
      zhishibiaoti = StrUtil.removeSuffix(zhishibiaoti, "%");
      queryBuilder.withQuery(
          boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("zhishibiaoti", zhishibiaoti)));
    }
    log.info(boolQueryBuilder.toString());
    // 转化成ES的页面查询条件
    queryBuilder
        .withPageable(PageRequest.of(Integer.parseInt(pageNo) - 1, Integer.parseInt(limit)));
    Page<ZhishixinxiEntity> pageResult = zhishixinxiRepository.search(queryBuilder.build());
    PageUtils pageUtils = new PageUtils(pageResult.getContent(),
        Convert.convert(new TypeReference<Integer>() {
        }, pageResult.getTotalElements()), pageResult.getSize(), pageResult.getNumber());
    return R.ok().put("data", pageUtils);
  }

  /**
   * 列表
   */
  @RequestMapping("/lists")
  public R list(ZhishixinxiEntity zhishixinxi) {
    EntityWrapper<ZhishixinxiEntity> ew = new EntityWrapper<ZhishixinxiEntity>();
    ew.allEq(MPUtil.allEQMapPre(zhishixinxi, "zhishixinxi"));
    return R.ok().put("data", zhishixinxiService.selectListView(ew));
  }

  /**
   * 查询
   */
  @RequestMapping("/query")
  public R query(ZhishixinxiEntity zhishixinxi) {
    EntityWrapper<ZhishixinxiEntity> ew = new EntityWrapper<ZhishixinxiEntity>();
    ew.allEq(MPUtil.allEQMapPre(zhishixinxi, "zhishixinxi"));
    ZhishixinxiView zhishixinxiView = zhishixinxiService.selectView(ew);
    return R.ok("查询知识信息成功").put("data", zhishixinxiView);
  }

  /**
   * 后端详情
   */
  @RequestMapping("/info/{id}")
  public R info(@PathVariable("id") String id) {
//    ZhishixinxiEntity zhishixinxi = zhishixinxiService.selectById(id);
//    zhishixinxi.setClicknum(zhishixinxi.getClicknum() + 1);
//    zhishixinxi.setClicktime(new Date());
//    zhishixinxiService.updateById(zhishixinxi);
    ZhishixinxiEntity zhishixinxiEntity = zhishixinxiRepository.findById(id).get();
    zhishixinxiEntity.setClicknum(zhishixinxiEntity.getClicknum() + 1);
    zhishixinxiEntity.setClicktime(new Date());
    updateObj(zhishixinxiEntity);
    return R.ok().put("data", zhishixinxiEntity);
  }

  /**
   * 前端详情
   */
  @IgnoreAuth
  @RequestMapping("/detail/{id}")
  public R detail(@PathVariable("id") String id) {
//    ZhishixinxiEntity zhishixinxi = zhishixinxiService.selectById(id);
//    zhishixinxi.setClicknum(zhishixinxi.getClicknum() + 1);
//    zhishixinxi.setClicktime(new Date());
//    zhishixinxiService.updateById(zhishixinxi);
//    return R.ok().put("data", zhishixinxi);
    ZhishixinxiEntity zhishixinxiEntity = null;
    Optional<ZhishixinxiEntity> optional = zhishixinxiRepository.findById(id);
    if (optional.isPresent()) {
      zhishixinxiEntity = optional.get();
    } else {
      return R.ok().put("data", zhishixinxiEntity);
    }
    zhishixinxiEntity.setClicknum(zhishixinxiEntity.getClicknum() + 1);
    zhishixinxiEntity.setClicktime(new Date());
    updateObj(zhishixinxiEntity);
    return R.ok().put("data", zhishixinxiEntity);
  }


  /**
   * 后端保存，改为ES
   */
  @RequestMapping("/save")
  public R save(@RequestBody ZhishixinxiEntity zhishixinxi, HttpServletRequest request) {
//    	zhishixinxi.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).toString());
//        zhishixinxiService.insert(zhishixinxi);
//        return R.ok();

    ZhishixinxiEntity save = zhishixinxiRepository.save(zhishixinxi);
    zhishixinxiService.insert(save);
    return R.ok();
  }

  /**
   * 前端保存，改为ES
   */
  @RequestMapping("/add")
  public R add(@RequestBody ZhishixinxiEntity zhishixinxi, HttpServletRequest request) {
//    zhishixinxi
//        .setId(new Date().getTime() + new Double(Math.floor(Math.random() * 1000)).toString());
    //ValidatorUtils.validateEntity(zhishixinxi);
//        zhishixinxiService.insert(zhishixinxi);
    ZhishixinxiEntity save = zhishixinxiRepository.save(zhishixinxi);
    zhishixinxiService.insert(save);
    return R.ok();
  }

  /**
   * 修改，改为ES
   */
  @RequestMapping("/update")
  public R update(@RequestBody ZhishixinxiEntity zhishixinxi, HttpServletRequest request) {
        zhishixinxiService.updateById(zhishixinxi);
//        return R.ok();
    updateObj(zhishixinxi);
    return R.ok();
  }

  private void updateObj(ZhishixinxiEntity zhishixinxiEntity) {
    Map<String, Object> sourceMap = Convert.convert(new TypeReference<Map<String, Object>>() {
    }, zhishixinxiEntity);
    // 发布日期的日期格式一直有点问题，只能先删掉
    if(sourceMap.containsKey("faburiqi")) {
      sourceMap.put("faburiqi", null);
    }
    sourceMap.entrySet().removeIf(entry -> entry.getValue() == null);

    IndexRequest indexRequest = new IndexRequest();
    indexRequest.source(sourceMap);
    UpdateQueryBuilder updateQueryBuilder = new UpdateQueryBuilder();
    UpdateQuery updateQuery = updateQueryBuilder
        .withClass(ZhishixinxiEntity.class).
            withId(zhishixinxiEntity.getId())
        .withIndexRequest(indexRequest)
        .build();
    elasticsearchTemplate.update(updateQuery);
  }


  /**
   * 删除
   */
  @RequestMapping("/delete")
  public R delete(@RequestBody List<String> ids) {
//        zhishixinxiService.deleteBatchIds(Arrays.asList(ids));
    ids.forEach(id -> {
      zhishixinxiRepository.deleteById(id);
      zhishixinxiService.deleteById(id);
    });
    return R.ok();
  }

  /**
   * 提醒接口
   */
  @RequestMapping("/remind/{columnName}/{type}")
  public R remindCount(@PathVariable("columnName") String columnName, HttpServletRequest request,
      @PathVariable("type") String type, @RequestParam Map<String, Object> map) {
    map.put("column", columnName);
    map.put("type", type);

    if (type.equals("2")) {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      Calendar c = Calendar.getInstance();
      Date remindStartDate = null;
      Date remindEndDate = null;
      if (map.get("remindstart") != null) {
        Integer remindStart = Integer.parseInt(map.get("remindstart").toString());
        c.setTime(new Date());
        c.add(Calendar.DAY_OF_MONTH, remindStart);
        remindStartDate = c.getTime();
        map.put("remindstart", sdf.format(remindStartDate));
      }
      if (map.get("remindend") != null) {
        Integer remindEnd = Integer.parseInt(map.get("remindend").toString());
        c.setTime(new Date());
        c.add(Calendar.DAY_OF_MONTH, remindEnd);
        remindEndDate = c.getTime();
        map.put("remindend", sdf.format(remindEndDate));
      }
    }

    Wrapper<ZhishixinxiEntity> wrapper = new EntityWrapper<ZhishixinxiEntity>();
    if (map.get("remindstart") != null) {
      wrapper.ge(columnName, map.get("remindstart"));
    }
    if (map.get("remindend") != null) {
      wrapper.le(columnName, map.get("remindend"));
    }

    String tableName = request.getSession().getAttribute("tableName").toString();
    if (tableName.equals("yonghu")) {
      wrapper.eq("yonghuzhanghao", (String) request.getSession().getAttribute("username"));
    }

    int count = zhishixinxiService.selectCount(wrapper);
    return R.ok().put("count", count);
  }

  /**
   * 前端智能排序
   */
  @IgnoreAuth
  @RequestMapping("/autoSort")
  public R autoSort(@RequestParam Map<String, Object> params, ZhishixinxiEntity zhishixinxi,
      HttpServletRequest request, String pre) {
//    EntityWrapper<ZhishixinxiEntity> ew = new EntityWrapper<ZhishixinxiEntity>();
//    Map<String, Object> newMap = new HashMap<String, Object>();
//    Map<String, Object> param = new HashMap<String, Object>();
//    Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
//    while (it.hasNext()) {
//      Map.Entry<String, Object> entry = it.next();
//      String key = entry.getKey();
//      String newKey = entry.getKey();
//      if (pre.endsWith(".")) {
//        newMap.put(pre + newKey, entry.getValue());
//      } else if (StringUtils.isEmpty(pre)) {
//        newMap.put(newKey, entry.getValue());
//      } else {
//        newMap.put(pre + "." + newKey, entry.getValue());
//      }
//    }
//    params.put("sort", "clicknum");
//    params.put("order", "desc");
//    PageUtils page = zhishixinxiService.queryPage(params,
//        MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, zhishixinxi), params), params));
//    return R.ok().put("data", page);
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    String pageNo = (String) params.get("page");
    String limit = (String) params.get("limit");

    // 转化成ES的页面查询条件
    queryBuilder
        .withPageable(PageRequest.of(Integer.parseInt(pageNo) - 1, Integer.parseInt(limit)));
    queryBuilder.withSort(SortBuilders.fieldSort("clicknum").order(SortOrder.DESC));
    Page<ZhishixinxiEntity> pageResult = zhishixinxiRepository.search(queryBuilder.build());
    PageUtils pageUtils = new PageUtils(pageResult.getContent(),
        Convert.convert(new TypeReference<Integer>() {
        }, pageResult.getTotalElements()), pageResult.getSize(), pageResult.getNumber());
    return R.ok().put("data", pageUtils);
  }


}
